#include "structMeshIdxTranslation.hpp"
#include "mpiH_Comm.hpp"
#include <catch2/catch_test_macros.hpp>

using namespace hms;

TEST_CASE( "Edge index translation" ){
	/***************************************************************************
	 * global mesh (size 6x5):
	 *   _________________________________________
	 *  |  30  |  31  |  32  |  33  |  34  |  35  |
	 * 64     65     66     67     68     69     70
	 *  |______|______|______|______|______|______|
	 *  |  24  |  25  |  26  |  27  |  28  |  29  |
	 * 57     58     59     60     61     62     63
	 *  |______|______|______|______|______|______|
	 *  |  18  |  19  |  20  |  21  |  22  |  23  |
	 * 50     51     52     53     54     55     56
	 *  |______|______|______|______|______|______|
	 *  |  12  |  13  |  14  |  15  |  16  |  17  |
	 * 43     44     45     46     47     48     49
	 *  |______|______|______|______|______|______|
	 *  |   6  |   7  |   8  |   9  |  10  |  11  |
	 * 36     37     38     39     40     41     42
	 *  |______|______|______|______|______|______|
	 *      0      1      2      3      4      5
	 * 
	 * local mesh (size 2x3, offset {3,1})
	 *   _________________________________________
	 *  |      |      |      |      |      |      |
	 *  |      |      |                           |
	 *  |______|______|___    ______ ______    ___|
	 *  |      |      |      |   6  |   7  |      |
	 *  |      |      |     14     15     16      |
	 *  |______|______|___   |______|______|   ___|
	 *  |      |      |      |   4  |   5  |      |
	 *  |      |      |     11     12     13      |
	 *  |______|______|___   |______|______|   ___|
	 *  |      |      |      |   2  |   3  |      |
	 *  |      |      |      8      9     10      |
	 *  |______|______|___   |______|______|   ___|
	 *  |      |      |          0      1         |
	 *  |      |      |                           |
	 *  |______|______|______|______|______|______|
	 * 
	 **************************************************************************/
	Array2i meshSizeGlobal { 6, 5 };
	Array2i meshSizeLocal  { 2, 3 };
	Array2i offset         { 3, 1 };
	Array2Xi indices (2, 17);
	/* upper row are the local indices, lower row the global ones */
	indices <<
		0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
		9, 10, 15, 16, 21, 22, 27, 28, 46, 47, 48, 53, 54, 55, 60, 61, 62;
	SECTION( "Local to global" ){
		SECTION( "horizontal"){
			for ( Index i{0}; i<8; ++i )
				REQUIRE( hEdgeLocalToGlobal(
					indices(0,i), meshSizeGlobal, meshSizeLocal, offset
				) == indices(1,i) );
		}
		SECTION( "vertical" ){
			for ( Index i{8}; i<indices.cols(); ++i )
				REQUIRE( vEdgeLocalToGlobal(
					indices(0,i), meshSizeGlobal, meshSizeLocal, offset
				) == indices(1,i) );
		}
		SECTION( "auto" ){
			for (Index i{0}; i<indices.cols(); ++i)
				REQUIRE( edgeLocalToGlobal(
					indices(0,i), meshSizeGlobal, meshSizeLocal, offset
				) == indices(1,i) );
		}
	}
	SECTION( "Global to local" ){
		SECTION( "horizontal" ){
			for ( Index i{0}; i<8; ++i )
				REQUIRE( hEdgeGlobalToLocal(
					indices(1,i), meshSizeGlobal, meshSizeLocal, offset
				) == indices(0,i) );
		}
		SECTION( "vertical" ){
			for ( Index i{8}; i<indices.cols(); ++i )
				REQUIRE( vEdgeGlobalToLocal(
					indices(1,i), meshSizeGlobal, meshSizeLocal, offset
				) == indices(0,i) );
		}
		SECTION( "auto" ){
			for (Index i{0}; i<indices.cols(); ++i)
				REQUIRE( edgeGlobalToLocal(
					indices(1,i), meshSizeGlobal, meshSizeLocal, offset
				) == indices(0,i) );
		}
	}
}